/*                                                              *
 * Project name : "Meteor" engine                               *
 * Version      : 1.8                                           *
 * Date         : 2000                                          *
 *                                                              *
 * Copyright    : dReddi                                        *
 * Description  : Main GameAI.dll include header                *
 */

#ifndef GAMEAI_H
#define GAMEAI_H

// Compilation type

#define GAMEAI_PROJECT

// DLL export macro

#define DLLExport                       __declspec(dllexport)

// Engine types

#define TRUE                            1
#define FALSE                           0

#define M_void                          void
#define M_boolean                       unsigned char
#define M_byte                          signed char
#define M_ubyte                         unsigned char
#define M_char                          char
#define M_short                         short
#define M_ushort                        unsigned short
#define M_int                           int
#define M_uint                          unsigned int
#define M_float                         float
#define M_double                        double

// Engine classes

#define CLASS_GAME                      1
#define CLASS_ACTOR                     2
#define THIS_ACTOR                      this

// Engine defines

#define TIMER_FREQ                      20
#define FILE_NAME_LENGTH                32
#define MAX_CONSOLE_LINE_LENGTH         64
#define MAX_LINE_PARAMS                 16

// Engine video modes

#define vid320x200                      1
#define vid400x300                      2
#define vid512x384                      3
#define vid640x480                      4
#define vid800x600                      5
#define vid1024x768                     6
#define vid1280x1024                    7
#define vid2048x1280                    8

// Engine variables

#define V_PauseRenderer                 *PauseRenderer
#define V_PausePhysics                  *PausePhysics
#define V_UseTextures                   *UseTextures
#define V_UseShading                    *UseShading
#define V_UseBlending                   *UseBlending
#define V_UseMirrors                    *UseMirrors
#define V_UseFog                        *UseFog
#define V_UseCoronas                    *UseCoronas
#define V_UseUnderWaterEffect           *UseUnderWaterEffect
#define V_UseWaterCaustic               *UseWaterCaustic
#define V_UseModels                     *UseModels
#define V_UseSounds                     *UseSounds
#define V_UseParticles                  *UseParticles
#define V_UsePanoramaSky                *UsePanoramaSky
#define V_UseSkyLayers                  *UseSkyLayers
#define V_GravityG                      *GravityG
#define V_ConsolePromptChar             *ConsolePromptChar
#define V_ConsoleMaxDropY               *ConsoleMaxDropY
#define V_ConsoleDropSpeed              *ConsoleDropSpeed
#define V_ConsoleFontsXSpace            *ConsoleFontsXSpace
#define V_ConsoleFontsYSpace            *ConsoleFontsYSpace
#define V_ConsoleFontsWidth             *ConsoleFontsWidth
#define V_ConsoleFontsHeight            *ConsoleFontsHeight
#define V_ConsoleBorderWidth            *ConsoleBorderWidth
#define V_ConsoleActive                 *ConsoleActive
#define V_ConsoleImage                  *ConsoleImage
#define V_ConsoleFontsImage             *ConsoleFontsImage
#define V_ConsoleFonts                  *ConsoleFonts
#define V_CaptureMouse                  *CaptureMouse 
#define V_ViewClipX1                    *ViewClipX1
#define V_ViewClipX2                    *ViewClipX2
#define V_ViewClipY1                    *ViewClipY1
#define V_ViewClipY2                    *ViewClipY2
#define V_Fov                           *Fov
#define V_OpenGLDll                     *OpenGLDll
#define V_TexturesQuality               *TexturesQuality
#define V_TexturesFiltering             *TexturesFiltering
#define V_VideoMode                     *VideoMode
#define V_FullScreen                    *FullScreen
#define V_WindowWidth                   *WindowWidth
#define V_WindowHeight                  *WindowHeight
#define V_SoundQuality                  *SoundQuality
#define V_SoundBits                     *SoundBits
#define V_SFXVolume                     *SFXVolume
#define V_MusicVolume                   *MusicVolume
#define V_SoundChannels                 *SoundChannels
#define V_FPS                           *FPS
#define V_ScreenYOfs                    *ScreenYOfs
#define V_ActorX                        *ActorX
#define V_ActorY                        *ActorY
#define V_ActorZ                        *ActorZ
#define V_ActorAx                       *ActorAx
#define V_ActorAy                       *ActorAy
#define V_ActorAz                       *ActorAz
#define V_ActorSector                   *ActorSector
#define V_ActorEnvironment              *ActorEnvironment
#define V_ActorOBBOxOXVector            (*ActorOBBOxOXVector)
#define V_ActorOBBOxOYVector            (*ActorOBBOxOYVector)
#define V_ActorOBBOxOZVector            (*ActorOBBOxOZVector)
#define V_ActorAllowXRotatedOBBox       *ActorAllowXRotatedOBBox
#define V_ActorAllowYRotatedOBBox       *ActorAllowYRotatedOBBox
#define V_ActorAllowZRotatedOBBox       *ActorAllowZRotatedOBBox
#define V_ActorVVector                  (*ActorVVector)
#define V_ActorRVector                  (*ActorRVector)
#define V_ActorWeight                   *ActorWeight
#define V_ActorDimX                     *ActorDimX
#define V_ActorDimY                     *ActorDimY
#define V_ActorDimZ                     *ActorDimZ

// Actor flags

#define actDynamicActor                 1
#define actStaticActor                  2
#define actPlayerActor                  actDynamicActor

// Actor environment

#define envAir                          1
#define envGround                       2
#define envWade                         3
#define envUnderWater                   4

// Engine types

#ifndef METEOR_PROJECT

typedef char M_String16[17];
typedef char M_String64[65];

typedef struct _M_ExtCommand {
    M_uint     command;
    M_int      infoint[3];
    M_float    infofloat[3];
    M_ubyte    infobool;
    M_String64 infostring;
} M_ExtCommand;

typedef struct _M_Vertex3d {
    M_float  x,y,z;
} M_Vertex3d;

typedef struct _M_Vertex2d {
    M_float  x,y;
} M_Vertex2d;

typedef struct _M_Camera {
    M_Vertex3d position;
    M_Vertex3d orientation;
    M_ushort   sector;
} M_Camera;

typedef struct _M_MapStart {
    M_String16 mapname;
    M_Vertex3d position;
    M_Vertex3d orientation;
    M_ushort   sector;
} M_MapStart;

typedef struct _M_ActorData {
    M_Vertex3d position;
    M_Vertex3d orientation;
    M_ushort   sector;
    M_int      infoint[3];
    M_float    infofloat[3];
    M_String64 infostring;
} M_ActorData;

#endif

// CMeteor base class

class DLLExport CMeteorBase {

    public:

        // Pointers to system variables ( immediate action )

        M_int           *PauseRenderer;
        M_int           *PausePhysics;
        
        M_int           *UseTextures;
        M_int           *UseShading;
        M_int           *UseBlending;
        M_int           *UseMirrors;
        M_int           *UseFog;
        M_int           *UseCoronas;
        M_int           *UseUnderWaterEffect;
        M_int           *UseWaterCaustic;
        M_int           *UseModels;
        M_int           *UseSounds;
        M_int           *UseParticles;
        M_int           *UsePanoramaSky;
        M_int           *UseSkyLayers;

        M_float         *GravityG;
         
        M_int           *ConsoleActive;        
        M_char          *ConsolePromptChar;
        M_float         *ConsoleMaxDropY,*ConsoleDropSpeed;
        M_uint          *ConsoleFontsXSpace,*ConsoleFontsYSpace;
        M_uint          *ConsoleFontsWidth,*ConsoleFontsHeight;
        M_uint          *ConsoleBorderWidth;
        M_uint          *ConsoleImage;
        M_uint          *ConsoleFontsImage;
        M_uint          *ConsoleFonts;

        M_int           *CaptureMouse;

        // Pointers to system variables ( action after CommitRenderChanges )

        M_char          *OpenGLDll;
        M_uint          *TexturesQuality;
        M_uint          *TexturesFiltering;
        M_uint          *VideoMode;
        M_int           *FullScreen;
        M_uint          *WindowWidth;
        M_uint          *WindowHeight;

        // Pointers to system variables ( action after CommitSoundChanges )

        M_uint          *SoundQuality;
        M_uint          *SoundBits;
        M_uint          *SoundChannels;
        M_uint          *SFXVolume,*MusicVolume;

        // Pointers to system variables ( read only )
        
        M_uint          *FPS;
        M_uint          *ScreenYOfs;
        
        // Pointers to system procedures

        M_int           (*AddActor)(M_char*,M_ActorData,M_ubyte,M_uint&);
        M_int           (*AddResourcePath)(M_char*,M_char*);
        M_void          (*BindMeteorProcs)(CMeteorBase*);
        M_void          (*BindMeteorVars)(CMeteorBase*);
        M_int           (*CommitRenderChanges)(M_void);
        M_int           (*CommitSoundChanges)(M_void);
        M_int           (*DeleteFonts)(M_uint&);
        M_int           (*DeleteImage)(M_uint&);
        M_int           (*DeleteMusic)(M_uint&);
        M_int           (*DeleteSample)(M_uint&);
        M_void          (*DrawText)(M_uint,M_char*,M_int,M_int,M_ubyte,M_ubyte,M_float);
        M_void          (*DropConsole)(M_int);
        M_int           (*EndGame)(M_void);
        M_int           (*ExecConfigFile)(M_char*);
        M_void          (*ExecuteConsoleCommand)(M_char*);
        M_short         (*GetKeyCode)(M_char*);
        M_int           (*GetMapStart)(M_char*,M_MapStart&);
        M_void          (*GetMouseMove)(M_int&,M_int&);        
        M_void          (*InsertConsoleLine)(M_char*);
        M_void          (*InsertExternalCommand)(M_void*);
        M_int           (*IsKeyDown)(M_short);
        M_void          (*LastKeyPressed)(M_short&,M_short&);
        M_int           (*LoadDemo)(M_char*);
        M_int           (*LoadImage)(M_char*,M_uint&);
        M_int           (*LoadMap)(M_char*);
        M_int           (*LoadMusic)(M_char*,M_uint&);
        M_int           (*LoadSample)(M_char*,M_uint&);
        M_int           (*LoadTransparentImage)(M_char*,M_uint&,M_ubyte,M_ubyte,M_ubyte);
        M_int           (*MakeFonts)(M_uint,M_uint&,M_ubyte,M_ubyte,M_ubyte,M_ubyte,M_ubyte,M_ubyte,M_ubyte);
        M_int           (*NewGame)(M_void);
        M_int           (*PlayAnimation)(M_void);
        M_int           (*PlayMusic)(M_uint);
        M_int           (*PlayMusicByName)(M_char*);
        M_int           (*PlaySample)(M_uint);
        M_int           (*PlaySample3d)(M_uint*,M_float,M_float,M_float);
        M_void          (*PrepareFonts)(M_uint);
        M_void          (*QuitEngine)(M_void);
        M_void          (*RaiseConsole)(M_int);
        M_int           (*RemoveActor)(M_uint);
        M_void          (*RenderImage)(M_uint,M_int,M_int,M_int,M_int,M_float);
        M_int           (*SaveWindowBmp)(M_char*);
        M_void          (*SendExternalCommand)(M_void*);
        M_void          (*SetGamma)(M_float);
        M_void          (*SetViewPort)(M_float,M_float,M_float,M_float,M_uint);
        M_int           (*StopMusic)(M_void);
        M_int           (*UnLoadDemo)(M_void);
        M_int           (*UnLoadMap)(M_void);
        M_void          (*UpdateCameraFPPView)(M_Camera*);
        M_void          (*UpdateCameraTPPView)(M_Camera*);
};

// CActor base class

class DLLExport CActorBase:public CMeteorBase {

    public:

        // Pointer to actor's internal data structure

        M_void          *ActorData;

        // Pointers to actor's variables ( read only )
        
        M_float         *ActorX,*ActorY,*ActorZ;
        M_float         *ActorAx,*ActorAy,*ActorAz;
        M_ushort        *ActorSector;
        M_ubyte         *ActorEnvironment;
        M_Vertex3d      *ActorOBBOxOXVector;
        M_Vertex3d      *ActorOBBOxOYVector;
        M_Vertex3d      *ActorOBBOxOZVector;
        
        // Pointers to actor's variables ( immediate action )

        M_int           *ActorAllowXRotatedOBBox;
        M_int           *ActorAllowYRotatedOBBox;
        M_int           *ActorAllowZRotatedOBBox;
        M_Vertex3d      *ActorVVector;
        M_Vertex3d      *ActorRVector;
        M_float         *ActorWeight;
        M_float         *ActorDimX,*ActorDimY,*ActorDimZ;

        // Pointers to actor procedures

        M_void          (*ApplyPhysics)(CActorBase*);
        M_void          (*Jump)(CActorBase*,M_float);
        M_void          (*Move)(CActorBase*,M_float,M_float,M_float,M_float);
        M_void          (*Strafe)(CActorBase*,M_float,M_float,M_float,M_float);
        M_void          (*Turn)(CActorBase*,M_float,M_float,M_float);
           
        /*
           Called when a new actor class was created.
        */
        virtual M_int Init(M_ActorData) { return FALSE; };
        /*
           Called when a actor class is about to be destroyed.
        */
        virtual M_int Done(M_void) { return FALSE; };
        /*
           Called when a new map was loaded.
           First parameter is a map file name.
        */
        virtual M_void MapChanged(M_char*) { };
        /*
           Timer procedure.Called every EVENT_FREQ milliseconds.
           Inside this procedure,user can call ONLY THIS system procedures:
                IsKeyDown(M_short)
                LastKeyPressed(M_short&,M_short&)
                GetKeyCode(M_char*)
                InsertConsoleLine(M_char*)
                ExecuteConsoleCommand(M_char*)
                SendExternalCommand(M_void*)
                InsertExternalCommand(M_void*)
                UpdateCameraFPPView(Camera&)
                UpdateCameraTPPView(Camera&)
            ...and all actor procedures.
        */
        virtual M_void Timer(M_void) { };
        /*
           Called when a new external command was sent.
           First parameter is pointer to ExtCommand structure.
        */
        virtual M_void ParseExternalCommand(M_ExtCommand*) { };
};

// CGame class

class DLLExport CGame:public CMeteorBase {
    public:
        /*
           Called when a new CGame class was created.
        */
        virtual M_int   Init(M_void) { return FALSE; };
        /*
           Called after creating rendering context.
           Inside this procedure user can load images,samples etc.
        */
        virtual M_int   Init2(M_void) { return FALSE; };
        /*
           Called when a CGame class is about to be destroyed.
        */
        virtual M_int   Done(M_void) { return FALSE; };
        /*
           Timer procedure.Called every EVENT_FREQ milliseconds.
           Inside this procedure,user can call ONLY THIS system procedures:
                IsKeyDown(M_short)
                LastKeyPressed(M_short&,M_short&)
                GetKeyCode(M_char*)
                InsertConsoleLine(M_char*)
                ExecuteConsoleCommand(M_char*)
                SendExternalCommand(M_void*
                InsertExternalCommand(M_void*)
                UpdateCameraFPPView(Camera&)
                UpdateCameraTPPView(Camera&)
            ...and all actor procedures.
        */
        virtual M_void  Timer(M_void) { };
        /*
           Called after 2d projection matrix was set.
        */
        virtual M_void  Render2d(M_void) { };
        /*
           Called after 3d projection matrix was set.
        */
        virtual M_void  Render3d(M_void) { };
        /*
           Called when a new external command was sent.
           First parameter is pointer to ExtCommand structure.
        */
        virtual M_void  ParseExternalCommand(M_ExtCommand*) { };
        /*
           Called when a new console command was entered.
           First parameter is number of parameters in command.
           Second parameter is a pointer to commands.
        */
        virtual M_void  ParseConsoleCommand(M_int,M_char**) { };
};

// Types

typedef CMeteorBase     *PMeteorBase;
typedef CActorBase      *PActorBase;
typedef CGame           *PGame;

// DLL procedures

extern "C" DLLExport void* GetClassPtr(int,char*);
extern "C" DLLExport void  FreeClassPtr(int,void*);

#endif